package com.zshy.base.monitor.domain.contract.dto;

import com.alibaba.fastjson2.annotation.JSONField;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;

import java.util.List;

/**
 * 企微 msg
 *
 * @author zhouhengzhe
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class MsgDTO {
    /**
     * 消息类型。
     * 目前有text,markdown,image,news,file,textcard,news（图文消息）,feedCard（feed流卡片）消息类型
     *
     * @see com.zshy.base.monitor.domain.contract.enums.QiWeiMsgTypeEnum
     */
    @JSONField(name = "msgtype")
    @NotBlank(message = "msgType不能为空")
    private String msgType;
    /**
     * 文本类型
     * {
     * "msgtype": "text",
     * "text": {
     * "content": "广州今日天气：29度，大部分多云，降雨概率：60%",
     * "mentioned_list":["wangqing","@all"],
     * "mentioned_mobile_list":["13800001111","@all"]
     * }
     * }
     */
    private TextDTO text;
    /**
     * markdown类型
     * <p>
     * {
     * "msgtype": "markdown",
     * "markdown": {
     * "content": "实时新增用户反馈<font color=\"warning\">132例</font>，请相关同事注意。\n
     * >类型:<font color=\"comment\">用户反馈</font>
     * >普通用户反馈:<font color=\"comment\">117例</font>
     * >VIP用户反馈:<font color=\"comment\">15例</font>"
     * }
     * }
     */
    private MarkDownDTO markdown;
    /**
     * 图片类型
     * {
     * "msgtype": "image",
     * "image": {
     * "base64": "DATA",
     * "md5": "MD5"
     * }
     * }
     */
    private ImageDTO image;

    /**
     * 图文类型
     */
    private NewsDTO news;

    /**
     * 文件类型
     */
    private FileDTO file;

    /**
     * 语音类型
     */
    private VoiceDTO voice;

    /**
     * 模版卡片类型
     */
    @JSONField(name = "template_card")
    private TemplateCardDTO templateCard;


    /**
     * 文本消息
     * <a href="https://developer.work.weixin.qq.com/document/path/99110#%E6%96%87%E6%9C%AC%E7%B1%BB%E5%9E%8B">...</a>
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public static class TextDTO {

        /**
         * 文本内容，最长不超过2048个字节，必须是utf8编码
         */
        @Size(min = 1, max = 2048)
        private String content;

        /**
         * userid的列表，提醒群中的指定成员(@某个成员)，@all表示提醒所有人，如果开发者获取不到userid，可以使用mentioned_mobile_list
         */
        @JSONField(name = "mentioned_list")
        private List<String> mentionedList;

        /**
         * 手机号列表，提醒手机号对应的群成员(@某个成员)，@all表示提醒所有人
         */
        @JSONField(name = "mentioned_mobile_list")
        private List<String> mentionedMobileList;
    }

    /**
     * markdown消息
     * <a href="https://developer.work.weixin.qq.com/document/path/99110#markdown%E7%B1%BB%E5%9E%8B">...</a>
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public static class MarkDownDTO {
        /**
         * markdown内容，最长不超过4096个字节，必须是utf8编码
         */
        @Size(max = 4096)
        private String content;
    }

    /**
     * 图文消息
     * <a href="https://developer.work.weixin.qq.com/document/path/99110#%E5%9B%BE%E6%96%87%E7%B1%BB%E5%9E%8B">...</a>
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public static class NewsDTO {
        /**
         * 图文消息，一个图文消息支持1到8条图文
         */
        private List<ArticleDTO> articles;

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        public static class ArticleDTO {

            /**
             * 标题，不超过128个字节，超过会自动截断
             */
            @JSONField(name = "title")
            @NotBlank(message = "title不能为空")
            private String title;

            /**
             * 描述，不超过512个字节，超过会自动截断
             */
            @JSONField(name = "description")
            private String description;

            /**
             * 点击后跳转的链接。
             */
            @JSONField(name = "url")
            @NotBlank(message = "url不能为空")
            private String url;

            /**
             * 图文消息的图片链接，支持JPG、PNG格式，较好的效果为大图 1068*455，小图150*150。
             */
            @JSONField(name = "picurl")
            private String picUrl;
        }
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public static class ImageDTO {
        /**
         * 图片内容的base64编码
         */
        private String base64;

        /**
         * 图片内容（base64编码前）的md5值
         */
        private String md5;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public static class FileDTO {
        /**
         * 文件id，通过下文的文件上传接口获取
         */
        @JSONField(name = "media_id")
        private String mediaId;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public static class VoiceDTO {
        /**
         * 语音文件id，通过下文的文件上传接口获取
         */
        @JSONField(name = "media_id")
        private String mediaId;
    }


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    public static class TemplateCardDTO {

        /**
         * 模版卡片的模版类型：
         * - 文本通知模版卡片的类型为text_notice
         * - 图文展示模版卡片的类型为news_notice
         */
        @NotBlank(message = "模版卡片的模版类型不能为空")
        @JSONField(name = "card_type")
        private String cardType;
        /**
         * 卡片来源样式信息
         */
        private Source source;
        /**
         * 模版卡片的主要内容，包括一级标题和标题辅助信息
         */
        @NotNull(message = "模版卡片的主要内容不能为空")
        @JSONField(name = "main_title")
        private MainTitle mainTitle;
        /**
         * 关键数据样式
         */
        @JSONField(name = "emphasis_content")
        private EmphasisContent emphasisContent;
        /**
         * 引用文献样式，建议不与关键数据共用
         */
        @JSONField(name = "quote_area")
        private QuoteArea quoteArea;
        /**
         * 二级普通文本，建议不超过112个字。模版卡片主要内容的一级标题main_title.title和二级普通文本sub_title_text必须有一项填写
         */
        @Length(max = 112, message = "二级普通文本不能超过112个字")
        @JSONField(name = "sub_title_text")
        private String subTitleText;
        /**
         * 二级标题+文本列表，该字段可为空数组，但有数据的话需确认对应字段是否必填，列表长度不超过6
         */
        @Size(max = 6, message = "二级标题+文本列表长度不能超过6")
        @JSONField(name = "horizontal_content_list")
        private List<HorizontalContentList> horizontalContentList;
        /**
         * 跳转指引样式的列表，该字段可为空数组，但有数据的话需确认对应字段是否必填，列表长度不超过3
         */
        @Size(max = 3, message = "跳转指引样式的列表长度不能超过3")
        @JSONField(name = "jump_list")
        private List<JumpList> jumpList;
        /**
         * 整体卡片的点击跳转事件，text_notice模版卡片中该字段为必填项
         */
        @NotNull(message = "整体卡片的点击跳转事件不能为空")
        @JSONField(name = "card_action")
        private CardAction cardAction;

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        public static class Source {

            /**
             * 来源图片的url
             */
            @JSONField(name = "icon_url")
            private String iconUrl;
            /**
             * 来源图片的描述，建议不超过13个字
             */
            private String desc;
            /**
             * 来源文字的颜色，目前支持：0(默认) 灰色，1 黑色，2 红色，3 绿色
             */
            @JSONField(name = "desc_color")
            private Integer descColor;
        }

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        public static class MainTitle {

            /**
             * 一级标题，建议不超过26个字。模版卡片主要内容的一级标题main_title.title和二级普通文本sub_title_text必须有一项填写
             */
            @Length(max = 26, message = "一级标题不能超过26个字")
            private String title;
            /**
             * 标题辅助信息，建议不超过30个字
             */
            @Length(max = 30, message = "标题辅助信息不能超过30个字")
            private String desc;
        }

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        public static class EmphasisContent {
            /**
             * 关键数据样式的数据内容，建议不超过10个字
             */
            @Length(max = 10, message = "关键数据样式的数据内容不能超过10个字")
            private String title;
            /**
             * 关键数据样式的数据描述内容，建议不超过15个字
             */
            @Length(max = 15, message = "关键数据样式的数据")
            private String desc;
        }

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        public static class QuoteArea {
            /**
             * 引用文献样式区域点击事件，0或不填代表没有点击事件，1 代表跳转url，2 代表跳转小程序
             */
            private Integer type;
            /**
             * 点击跳转的url，quote_area.type是1时必填
             */
            private String url;
            /**
             * 点击跳转的小程序的appid，quote_area.type是2时必填
             */
            @JSONField(name = "appid")
            private String appId;
            /**
             * 点击跳转的小程序的pagepath，quote_area.type是2时选填
             */
            @JSONField(name = "pagepath")
            private String pagePath;
            /**
             * 引用文献样式的标题
             */
            private String title;
            /**
             * 引用文献样式的引用文案
             */
            @JSONField(name = "quote_text")
            private String quoteText;
        }

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        public static class HorizontalContentList {

            /**
             * 模版卡片的二级标题信息内容支持的类型，1是url，2是文件附件，3 代表点击跳转成员详情
             */
            private Integer type;
            /**
             * 二级标题，建议不超过5个字
             */
            @Length(max = 5, message = "二级标题不能超过5个字")
            @JSONField(name = "keyname")
            private String keyName;
            /**
             * 二级文本，如果horizontal_content_list.type是2，该字段代表文件名称（要包含文件类型），建议不超过26个字
             */
            @Length(max = 26, message = "二级文本不能超过26个字")
            private String value;
            /**
             * 链接跳转的url，horizontal_content_list.type是1时必填
             */
            private String url;
            /**
             * 附件的media_id，horizontal_content_list.type是2时必填
             */
            @JSONField(name = "media_id")
            private String mediaId;

            /**
             * 成员详情的userid，horizontal_content_list.type是3时必填
             */
            @JSONField(name = "userid")
            private String userId;
        }

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        public static class JumpList {

            /**
             * 跳转链接类型，0或不填代表不是链接，1 代表跳转url，2 代表跳转小程序
             */
            private Integer type;
            /**
             * 跳转链接样式的文案内容，建议不超过13个字
             */
            @Length(max = 13, message = "跳转链接样式的文案内容不能超过13个字")
            private String title;
            /**
             * 跳转链接的url，jump_list.type是1时必填
             */
            private String url;
            /**
             * 跳转链接的小程序的appid，jump_list.type是2时必填
             */
            @JSONField(name = "appid")
            private String appId;
            /**
             * 跳转链接的小程序的pagepath，jump_list.type是2时选填
             */
            @JSONField(name = "pagepath")
            private String pagePath;
        }

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        public static class CardAction {
            /**
             * 卡片跳转类型，1 代表跳转url，2 代表打开小程序。text_notice模版卡片中该字段取值范围为[1,2]
             */
            private Integer type;
            /**
             * 跳转事件的url，card_action.type是1时必填
             */
            private String url;
            /**
             * 跳转事件的小程序的appid，card_action.type是2时必填
             */
            @JSONField(name = "appid")
            private String appId;
            /**
             * 跳转事件的小程序的pagepath，card_action.type是2时选填
             */
            @JSONField(name = "pagepath")
            private String pagePath;
        }
    }
}